GET 请求缓存问题

您所在的位置:网站首页 ajax 解决浏览器缓存问题 GET 请求缓存问题

GET 请求缓存问题

2024-04-12 21:29| 来源: 网络整理| 查看: 265

缘起

关于get请求,不同浏览器间产生不同的问题,想必很多前端开发人员都遇到过。 常见的是ajax请求过一次以后,以后的相同 url 的 get 请求:

case 1 有时返回304,有时返回200; case 2 有时无论后台数据是否变化始终返回304,有时却始终返回200; 同一套代码在不同浏览器间结果不同;

禁止浏览器缓存数据网上常见的解决方案

1.在html页面设置Meta标签 结果:因浏览器不同或者同一浏览器间版本不同,这个方法有很大的兼容性,很多时候根本没有作用。 2. 在ajax的 URL 参数后面加时间戳或者随机数 $.ajax({ url: 'http://localhost/api/list', type: 'get', data: { _t: new Date().valueOf() //加时间戳 //_t: Math.random() 加随机数 }, success: function ( res ) { console.log(res); } }) 结果:这种方式虽然能解决IE始终返回304的问题,但实际上每个ajax都会去请求服务器,对web优化并非最佳的解决方案。 3. 用post请求替代get请求 结果: 不推荐,一是因为这种做法不符合RESTful API设计,二是因为这种方式同样会每次请求服务器,没有真正利用到浏览器自带的缓存功能。 想要实现的目的

首次请求返回200,数据不变的情况下,请求需和服务器确认返回304,如果有数据变化,则返回200,并且需要IE和google浏览器一致。

浏览器缓存机制

image.png

浏览器缓存主要由HTML Meta标签控制缓存和HTTP头信息控制缓存另外与用户行为也有关系,http头信息参数多,缺乏相关实践经验,理解起来复杂,难以记忆。大家可以参考HTTP 缓存策略

针对客户端的测试

服务端:express提供接口,客户端:jquery ajax发起请求 ,抓包工具fiddler,仅测试 cache-control 和 Pragma

//服务端不设置响应头,普通输出,每次输出数据不变化 app.get('/list', (req, res, next)=>{ Order.findAll({ where: { uuid: req.session.loginUser } }).then(result=>{ res.send({code:0, msg: '获取成功', data: result}); }).catch(err=>{ res.send({code:-1, data: '获取失败'}); }) }); //客户端 设置请求头 cache-control 和 Pragma $.ajax({ url: 'http://localhost/api/list', type: 'get', headers: { //当只设置cacahe-control: 'no-cache'时,IE浏览器始终返回304,抓包工具抓不到包,请求不和服务器确认 //当只设置cacahe-control: 'no-cache'时,google浏览器始终返回200,抓包工具可以抓取包,请求重新从服务器获取数据,没有利用到浏览器的缓存功能 'cache-control': 'no-cache', //当只设置Pragma: 'no-cache'时,IE浏览器始终返回200,抓包工具可以抓到所有包,请求重新从服务器获取数据,没有利用到浏览器的缓存功能 //当只设置Pragma: 'no-cache'时,google浏览器始终返回200,抓包工具可以抓到所有包,请求重新从服务器获取数据,没有利用到浏览器的缓存功能 'Pragma': 'no-cache' //两个参数同时不设置时,IE浏览器始终返回304,抓包工具抓不到包,请求不和服务器确认 //两个参数同时不设置时,google浏览器首次返回200,之后始终返回304,并且有和服务器确认 //两个参数同时设置时,IE浏览器始终返回200,抓包工具可以抓到所有包,请求重新从服务器获取数据,没有利用到浏览器的缓存功能 //两个参数同时设置时,google浏览器始终返回200,抓包工具可以抓到所有包,请求重新从服务器获取数据,没有利用到浏览器的缓存功能 }, success: function (res) { console.log(res); } }) 结果:

参数Pragma 设为"no-cache"时,IE和google每次从服务器获取数据,效果一致,始终不从缓存获取; 参数cache-control设为"no-cache"时,对IE浏览器无效,对google浏览器效果不理想,并未到达目的。 所以以上的方式以失败告终。

针对服务端的测试

抛开请求头,设置响应头。客户端:jquery ajax发起请求,服务端 express提供接口,抓包工具fiddler,仅设置服务端 'Cache-Control'

//服务端,设置响应头 Cache-Control app.get('/list', (req, res, next)=>{ res.set( { 'Cache-Control' : 'max-age=5' //便于测试,设置缓存时间5s; } ); Order.findAll({ where: { uuid: req.session.loginUser } }).then(result=>{ res.send({code:0, msg: '获取成功', data: result}); }).catch(err=>{ res.send({code:-1, data: '获取失败'}); }) }); //客户端,普通ajax,不做任何请求头设置 $.ajax({ url: 'http://localhost/api/list', type: 'get', headers: { }, success: function (res) { console.log(res); } }) IE浏览器测试结果

IE浏览器响应头: 在这里插入图片描述

IE浏览器ajax请求:

在这里插入图片描述

google浏览器测试结果

google浏览器响应头:

在这里插入图片描述

google浏览器ajax请求: 在这里插入图片描述

结论:后端设置响应头缓存时间5s,前端不做设置。 IE浏览器在首次请求后,5s内每次请求从缓存获取,不和服务器确认,直接返回304,超过5s就和服务器确认,如果服务器数据改变则返回200,数据没有改变返回304;之后的请求以此类推。 googole 浏览器在首次请求后,5s内每次请求从缓存获取,不和服务器确认,网络面板显示 code 200 ,size from cache,超过5s就和服务器确认,如果服务器数据改变则返回200,数据没有改变返回304;之后的请求以此类推。 这个方法与我想要的效果一致。假如希望每次都要和服务器确认,不直接从缓存获取,那么只需在后端设置cache-Control: 'max-age: 0'即可。

注意:因ajax类库众多,像$jquery ajax, angular-resource, vue-resouce, axios, 原生ajax等,可能默认的请求头设置会与我上面的不一样,可能出现不一样的结果。后端也是同样的问题。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3